/****************************************************************************
 * FILE NAME: 		timer.c
 * 
 * PROJECT NAME: 	EGR330_Project
 * TEAM MEMBERS: 	Kevin Vermeer
 * 					Brandon Ross
 *					Tyler Selk
 *
 * 
 * CREATED: 		1 August 2011 (Brandon Ross)
 * LAST MODIFIED: 		
 * 
 * DESCRIPTION:		Handles functions necessary to operate timer peripherals
 ****************************************************************************/

#include <avr/io.h>
#include <inttypes.h>

#include "timer.h"
#include "clock.h"
#include "generic.h"

/********************************** TIMER0 **********************************/

/*
 * FUNCTION NAME:	T0_selectClockSource
 * INPUTS:			T0_CLK_SOURCE (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Sets clock source for TIMER0
 */
void T0_selectClockSource(uint8_t T0_CLK_SOURCE)
{
	TCCR0B = setRegister(TCCR0B, T0_MASK_CS0X, T0_CLK_SOURCE, T0_POS_CS0X);
}

/*
 * FUNCTION NAME:	T0_writeValue
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to TIMER0 counter
 */
void T0_writeValue(uint8_t value)
{
	TCNT0 = value;
}

/*
 * FUNCTION NAME:	T0_readValue
 * INPUTS:			None
 * OUTPUTS:			TNCT0 (uint8_t)
 * DESCRIPTION:		Returns value in TIMER0 counter
 */
uint8_t T0_readValue(void)
{
	return(TCNT0);
}

/*
 * FUNCTION NAME:	T0_writeCompareA
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to Output Compare A
 */
void T0_writeCompareA(uint8_t value)
{
	OCR0A = value;
}

/*
 * FUNCTION NAME:	T0_writeCompareB
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to Output Compare B
 */
void T0_writeCompareB(uint8_t value)
{
	OCR0B = value;
}

/*
 * FUNCTION NAME:	T0_enableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Output Compare B match
 */
void T0_enableCompareBInterrupt(void)
{
	TIMSK0 = setBit(TIMSK0, T0_BIT_OCIE0B);
}

/*
 * FUNCTION NAME:	T0_enableCompareAInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Output Compare A match
 */
void T0_enableCompareAInterrupt(void)
{
	TIMSK0 = setBit(TIMSK0, T0_BIT_OCIE0A);
}

/*
 * FUNCTION NAME:	T0_enableOverflowInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Timer0 Overflow
 */
void T0_enableOverflowInterrupt(void)
{
	TIMSK0 = setBit(TIMSK0, T0_BIT_TOIE0);
}

/*
 * FUNCTION NAME:	T0_disableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER0 Compare B Interrupt
 */
void T0_disableCompareBInterrupt(void)
{
	TIMSK0 = clearBit(TIMSK0, T0_BIT_OCIE0B);
}

/*
 * FUNCTION NAME:	T0_disableCompareAInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER0 Compare A Interrupt
 */
void T0_disableCompareAInterrupt(void)
{
	TIMSK0 = clearBit(TIMSK0, T0_BIT_OCIE0A);
}

/*
 * FUNCTION NAME:	T0_disableOverflowInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disables TIMER0 Overflow Interrupt
 */
void T0_disableOverflowInterrupt(void)
{
	TIMSK0 = clearBit(TIMSK0, T0_BIT_TOIE0);
}

/*
 * FUNCTION NAME:	T0_resetCompareBFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears OCF0B bit (set-to-clear)
 */
void T0_resetCompareBFlag(void)
{
	TIFR0 = setBit(TIFR0, T0_BIT_OCF0B);
}

/*
 * FUNCTION NAME:	T0_resetCompareAFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears OCF0A bit (set-to-clear)
 */
void T0_resetCompareAFlag(void)
{
	TIFR0 = setBit(TIFR0, T0_BIT_OCF0A);
}

/*
 * FUNCTION NAME:	T0_resetOverflowFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears TOV0 bit (set-to-clear)
 */
void T0_resetOverflowFlag(void)
{
	TIFR0 = setBit(TIFR0, T0_BIT_TOV0);
}

/********************************** TIMER1 **********************************/

/*
 * FUNCTION NAME:	T1_selectClockSource
 * INPUTS:			T1_CLK_SOURCE (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Sets clock source for TIMER1
 */
void T1_selectClockSource(uint8_t T1_CLK_SOURCE)
{
	TCCR1B = setRegister(TCCR1B, T1_MASK_CS1X, T1_CLK_SOURCE, T1_POS_CS1X);
}

/*
 * FUNCTION NAME:	T1_writeValue
 * INPUTS:			value (uint16_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to TIMER1 counter
 */
void T1_writeValue(uint16_t value)
{
	TCNT1H = (uint8_t)(value>>8);
	TCNT1L = (uint8_t)value;
}

/*
 * FUNCTION NAME:	T1_readValue
 * INPUTS:			None
 * OUTPUTS:			value (uint16_t)
 * DESCRIPTION:		Returns value in TIMER1 counter
 */
uint16_t T1_readValue(void)
{
	uint16_t value = 0x0000;

	value = (((uint16_t)TCNT1H)<<8) | ((uint16_t)TCNT1L); 
	
	return(value);
}

/*
 * FUNCTION NAME:	T1_writeCompareA
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to Output Compare A
 */
void T1_writeCompareA(uint16_t value)
{
	OCR1AH = (uint8_t)(value>>8);
	OCR1AL = (uint8_t)value;
}

/*
 * FUNCTION NAME:	T1_writeCompareB
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to Output Compare B
 */
void T1_writeCompareB(uint16_t value)
{
	OCR1BH = (uint8_t)(value>>8);
	OCR1BL = (uint8_t)value;
}

/*
 * FUNCTION NAME:	T1_enableCaptureInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Input Capture match
 */
void T1_enableCaptureInterrupt(void)
{
	TIMSK1 = setBit(TIMSK1, T1_BIT_ICIE1);
}

/*
 * FUNCTION NAME:	T1_enableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Output Compare B match
 */
void T1_enableCompareBInterrupt(void)
{
	TIMSK1 = setBit(TIMSK1, T1_BIT_OCIE1B);
}

/*
 * FUNCTION NAME:	T1_enableCompareAInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Output Compare A match
 */
void T1_enableCompareAInterrupt(void)
{
	TIMSK1 = setBit(TIMSK1, T1_BIT_OCIE1A);
}

/*
 * FUNCTION NAME:	T1_enableOverflowInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Timer1 Overflow
 */
void T1_enableOverflowInterrupt(void)
{
	TIMSK1 = setBit(TIMSK1, T1_BIT_TOIE1);
}

/*
 * FUNCTION NAME:	T1_disableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER1 Input Capture Interrupt
 */
void T1_disableCaptureInterrupt(void)
{
	TIMSK1 = clearBit(TIMSK1, T1_BIT_ICIE1);
}

/*
 * FUNCTION NAME:	T1_disableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER1 Compare B Interrupt
 */
void T1_disableCompareBInterrupt(void)
{
	TIMSK1 = clearBit(TIMSK1, T1_BIT_OCIE1B);
}

/*
 * FUNCTION NAME:	T1_disableCompareAInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER1 Compare A Interrupt
 */
void T1_disableCompareAInterrupt(void)
{
	TIMSK1 = clearBit(TIMSK1, T1_BIT_OCIE1A);
}

/*
 * FUNCTION NAME:	T1_disableOverflowInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disables TIMER1 Overflow Interrupt
 */
void T1_disableOverflowInterrupt(void)
{
	TIMSK1 = clearBit(TIMSK1, T1_BIT_TOIE1);
}

/*
 * FUNCTION NAME:	T1_resetCaptureFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears ICF1 bit (set-to-clear)
 */
void T1_resetCaptureFlag(void)
{
	TIFR1 = setBit(TIFR1, T1_BIT_ICF1);
}

/*
 * FUNCTION NAME:	T1_resetCompareBFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears OCF1B bit (set-to-clear)
 */
void T1_resetCompareBFlag(void)
{
	TIFR1 = setBit(TIFR1, T1_BIT_OCF1B);
}

/*
 * FUNCTION NAME:	T1_resetCompareAFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears OCF1A bit (set-to-clear)
 */
void T1_resetCompareAFlag(void)
{
	TIFR1 = setBit(TIFR1, T1_BIT_OCF1A);
}

/*
 * FUNCTION NAME:	T1_resetOverflowFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears TOV1 bit (set-to-clear)
 */
void T1_resetOverflowFlag(void)
{
	TIFR1 = setBit(TIFR1, T1_BIT_TOV1);
}

/********************************** TIMER2 **********************************/

/*
 * FUNCTION NAME:	T2_selectClockSource
 * INPUTS:			T2_CLK_SOURCE (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Sets clock source for TIMER2
 */
void T2_selectClockSource(uint8_t T2_CLK_SOURCE)
{
	TCCR2B = setRegister(TCCR2B, T2_MASK_CS2X, T2_CLK_SOURCE, T2_POS_CS2X);
}

/*
 * FUNCTION NAME:	T2_writeValue
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to TIMER2 counter
 */
void T2_writeValue(uint8_t value)
{
	TCNT2 = value;
}

/*
 * FUNCTION NAME:	T2_readValue
 * INPUTS:			None
 * OUTPUTS:			TNCT2 (uint8_t)
 * DESCRIPTION:		Returns value in TIMER2 counter
 */
uint8_t T2_readValue(void)
{
	return(TCNT2);
}

/*
 * FUNCTION NAME:	T2_writeCompareA
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to Output Compare A
 */
void T2_writeCompareA(uint8_t value)
{
	OCR2A = value;
}

/*
 * FUNCTION NAME:	T2_writeCompareA
 * INPUTS:			value (uint8_t)
 * OUTPUTS:			None
 * DESCRIPTION:		Writes value to Output Compare B
 */
void T2_writeCompareB(uint8_t value)
{
	OCR2B = value;
}

/*
 * FUNCTION NAME:	T2_enableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Output Compare B match
 */
void T2_enableCompareBInterrupt(void)
{
	TIMSK2 = setBit(TIMSK2, T2_BIT_OCIE2B);
}

/*
 * FUNCTION NAME:	T2_enableCompareAInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on Output Compare A match
 */
void T2_enableCompareAInterrupt(void)
{
	TIMSK2 = setBit(TIMSK2, T2_BIT_OCIE2A);
}

/*
 * FUNCTION NAME:	T2_enableOverflowInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Enables Interrupt on TIMER2 Overflow
 */
void T2_enableOverflowInterrupt(void)
{
	TIMSK2 = setBit(TIMSK2, T2_BIT_TOIE2);
}

/*
 * FUNCTION NAME:	T2_disableCompareBInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER2 Compare B Interrupt
 */
void T2_disableCompareBInterrupt(void)
{
	TIMSK2 = clearBit(TIMSK2, T2_BIT_OCIE2B);
}

/*
 * FUNCTION NAME:	T2_disableCompareAInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disable TIMER2 Compare A Interrupt
 */
void T2_disableCompareAInterrupt(void)
{
	TIMSK2 = clearBit(TIMSK2, T2_BIT_OCIE2A);
}

/*
 * FUNCTION NAME:	T2_disableOverflowInterrupt
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Disables TIMER2 Overflow Interrupt
 */
void T2_disableOverflowInterrupt(void)
{
	TIMSK2 = clearBit(TIMSK2, T2_BIT_TOIE2);
}

/*
 * FUNCTION NAME:	T2_resetCompareBFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears OCF2B bit (set-to-clear)
 */
void T2_resetCompareBFlag(void)
{
	TIFR2 = setBit(TIFR2, T2_BIT_OCF2B);
}

/*
 * FUNCTION NAME:	T2_resetCompareAFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears OCF2A bit (set-to-clear)
 */
void T2_resetCompareAFlag(void)
{
	TIFR2 = setBit(TIFR2, T2_BIT_OCF2A);
}

/*
 * FUNCTION NAME:	T2_resetOverflowFlag
 * INPUTS:			None
 * OUTPUTS:			None
 * DESCRIPTION:		Clears TOV2 bit (set-to-clear)
 */
void T2_resetOverflowFlag(void)
{
	TIFR2 = setBit(TIFR2, T2_BIT_TOV2);
}
